local Actor = require'entities.actor'

local Lifeform = {}
Lifeform.mt = { __index = Lifeform }
setmetatable( Lifeform, Actor.mt )


function Lifeform.initialize( type, health, deck, ship)

	local lf = Actor.new ( type, health, deck )
	setmetatable(lf, Lifeform.mt)
	
	if ship then 
		lf:board_ship( ship )
		lf.ship_id = ship.ship_id
		--ship.layer:insertProp( lf.prop )
	else 
		lf.ship_id = 0 
	end
	
	lf.hunger_max = 100
	lf.thirst_max = 100
	lf.piss_max = 100
	lf.shit_max = 100
	lf.hygene_max = 100
	lf.sleep_max = 100	
	
	lf.hunger = 100
	lf.thirst = 100
	lf.piss = 100
	lf.shit = 100
	lf.hygene = 100
	lf.sleep = 100
	
	lf.hunger_rate = BASE_HUNGER_RATE * GAME_SPEED
	lf.thirst_rate = BASE_THIRST_RATE * GAME_SPEED
	lf.piss_rate = BASE_PISS_RATE * GAME_SPEED
	lf.shit_rate = BASE_SHIT_RATE * GAME_SPEED
	lf.hygene_rate = BASE_HYGENE_RATE * GAME_SPEED
	lf.sleep_rate = BASE_SLEEP_RATE * GAME_SPEED
	lf.job_rate = BASE_JOB_RATE * GAME_SPEED
	
	lf.hunger_que = false
	lf.thirst_que = false
	lf.piss_que = false
	lf.shit_que = false
	lf.hygene_que = false
	lf.sleep_que = false
	lf.job_que = false
	
	lf.hunger_sel = 1
	lf.thirst_sel = 1
	lf.piss_sel = 1
	lf.shit_sel = 1
	lf.hygene_sel = 1
	lf.sleep_sel = 1
	lf.job_sel = 1
	
	
	lf.hunger_refresh = 10
	lf.thirst_refresh = 5
	lf.piss_refresh = 2
	lf.shit_refresh = 10
	lf.hygene_refresh = 20
	lf.sleep_refresh = 33
	
	lf.current_task = 'job'
	lf.default_task = 'job'
	
	lf.task_manager = {}
	
	
	return lf

end


function Lifeform.new( type, health, deck, ship )

	local o = Lifeform.initialize( type, health, deck, ship)
	
	
	return o

end

function Lifeform:upd(dt)
	if dt > 1 then dt = 1/dt end
	Actor.upd(self, dt)
	self.hunger = self.hunger - (self.hunger_rate*(dt*TURN_TIME))
	self.thirst = self.thirst - (self.thirst_rate*(dt*TURN_TIME))
	self.piss = self.piss - (self.piss_rate*(dt*TURN_TIME))
	self.shit = self.shit - (self.shit_rate*(dt*TURN_TIME))
	self.hygene = self.hygene - (self.hygene_rate*(dt*TURN_TIME))
	self.sleep = self.sleep - (self.sleep_rate*(dt*TURN_TIME))
	-- check our stats
	if self.hunger <= 0 and self.hunger_que == false then 
		self.hunger_que = true
		Lifeform.task_manager_add(self, HUNGER); 
		print("HUNGER eat queued") 
	elseif self.job_que == false then 
		Lifeform.task_manager_add(self,JOB) 
		self.job_que = true
	end
	if self.thirst <= 0 and self.thirst_que == false then 
		self.thirst_que = true
		Lifeform.task_manager_add(self, THIRST); 
		print("THIRST drink qeueued") 
	elseif self.job_que == false then 
		Lifeform.task_manager_add(self, JOB) 
		self.job_que = true
	end
	if self.piss <= 0  and self.piss_que == false then 
		self.piss_que = true
		Lifeform.task_manager_add(self, PISS); 
		print("PISS piss queued") 
	elseif self.job_que == false then 
		Lifeform.task_manager_add(self,JOB) 
		self.job_que = true
	end
	if self.shit <= 0 and self.shit_que == false then 
		self.shit_que = true
		Lifeform.task_manager_add(self, SHIT); 
		print("SHIT shit queued") 
	elseif self.job_que == false then 
		Lifeform.task_manager_add(self, JOB) 
		self.job_que = true
	end
	if self.hygene <= 0 and self.hygene_que == false then 
		self.hygene_que = true
		Lifeform.task_manager_add(self, HYGENE); 
		print("HYGENE wash queued") 
	elseif self.job_que == false then 
		Lifeform.task_manager_add(self, JOB) 
		self.job_que = true
	end
	if self.sleep <= 0 and self.sleep_que == false then 
		self.sleep_que = true
		Lifeform.task_manager_add(self, SLEEP); 
		print("SLEEP rest queued") 
	elseif self.job_que == false then	
		Lifeform.task_manager_add(self, JOB)
		self.job_que = true
	end

end

function Lifeform:task_do( task )


	local immediate_importance = {
			[JOB] = function(self) Lifeform.do_job(self) end,
			[PISS] = function(self) Lifeform.do_piss(self) end,
			[SHIT] = function(self) Lifeform.do_shit(self) end,
			[THIRST] = function(self) Lifeform.do_drink(self) end,
			[HUNGER] = function(self) Lifeform.do_eat(self) end,
			[HYGENE] = function(self) Lifeform.do_wash(self) end,
			[SLEEP] = function(self) Lifeform.do_sleep(self) end,
	}
	
	immediate_importance[task](self)


end

function Lifeform:task_manager_add( task )

	local self = Lifeform.get_self(self)

	if not self.task_manager then self.task_manager = {} end
	
	local iter = #self.task_manager+1
	
	self.task_manager[iter] = task	

end

function Lifeform:task_manager_next()

	table.remove(self.task_manager, 1)
	print("LIFEFORM TASK MAN NEXT")
	if self.task_manager[1] then
		self.current_task = self.task_manager[1]
	else
		self.current_task = self.default_task
	end
	
	self:task_do(self.current_task)

end

function Lifeform:refresh_time()

	lf.hunger_rate = lf.hunger_rate * GAME_SPEED
	lf.thirst_rate = lf.thirst_rate * GAME_SPEED
	lf.piss_rate = lf.piss_rate * GAME_SPEED
	lf.shit_rate = lf.shit_rate * GAME_SPEED
	lf.hygene_rate = lf.hygene_rate * GAME_SPEED
	lf.sleep_rate = lf.sleep_rate * GAME_SPEED
	lf.job_rate = lf.job_rate * GAME_SPEED
end

function Lifeform:do_job( spawn_at_station )

	if self.station then
	
		local x, y = self.station_x, self.station_y
		
		if spawn_at_station then
			self:seekLoc( x, y, 0.0000001 )
		else
			self:seekLoc( x, y, self.travel_speed )
		end
		
		local lf = self
		
		
		local it = #TM.timers+1
		TM.timers[it] = MOAITimer.new()
		local timer = TM.timers[it]
		timer:setSpan( 5 )
		
		timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
			function()
				--require('mobdebug').on() -- zerobrane
				print("LIFEFORM DO JOB timer off")
				lf.job_que = false
				lf:task_manager_next()
				timer:stop()
				timer = nil
			
			end
		)
		
		timer:start()
					
	
	end

end

function Lifeform:do_piss()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.st[self.piss_sel].x, stations.st[self.piss_sel].y
	

	if self.piss < 0 then
		if stations.st then
			
					local move_func = function(self, x, y, speed)
						local action = self.prop:seekLoc(x,y,speed)
						MOAICoroutine.blockOnAction( action )
						
						
						local lf = self
						local it = #TM.timers+1
						TM.timers[it] = MOAITimer.new()
						local timer = TM.timers[it]
						timer:setSpan( self.piss_refresh+speed )
						timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
							function()
							
								print("PISS timer up")
								lf.piss = lf.piss_max
								lf:task_manager_next()
								lf.piss_que = false
								timer:stop()
								timer = nil
							
							end
						)
						
						timer:start()
						
					end
					local thread = MOAICoroutine.new()
					thread:run(move_func, self, sx, sy, self.travel_speed)
					--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
				
			
			
		end
	
		
	end

end

function Lifeform:do_shit()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.st[self.shit_sel].x, stations.st[self.shit_sel].y

	if self.shit < 0 then
		if stations.st then
			
				
					local move_func = function(self, x, y, speed)
						local action = self.prop:seekLoc(x,y,speed)
						MOAICoroutine.blockOnAction( action )
						
						local lf = self
						local it = #TM.timers+1
						TM.timers[it] = MOAITimer.new()
						local timer = TM.timers[it]
						timer:setSpan( self.shit_refresh )
						timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
							function()
								print("SHIT timer up")
								lf.shit = lf.shit_max
								lf.shit_que = false
								lf:task_manager_next()
								timer:stop()
								timer = nil
							
							end
						)
						
						timer:start()
						
					end
					local thread = MOAICoroutine.new()
					thread:run(move_func, self, sx, sy, self.travel_speed)
					--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
				
			
			
		end
	
		
	end

end

function Lifeform:do_drink()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.fs[self.thirst_sel].x, stations.fs[self.thirst_sel].y

	if self.thirst < 0 then
		if stations.fs then
			
				
					local move_func = function(self, x, y, speed)
						local action = self.prop:seekLoc(x,y,speed)
						MOAICoroutine.blockOnAction( action )
						
						local lf = self
						local it = #TM.timers+1
						TM.timers[it] = MOAITimer.new()
						local timer = TM.timers[it]
						timer:setSpan( self.thirst_refresh )
						timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
							function()
								print("DRINK timer up")
								lf.thirst = lf.thirst_max
								lf.thirst_que = false
								lf:task_manager_next() 
								timer:stop()
								timer = nil
							
							end
						)
						
						timer:start()
						
					end
					local thread = MOAICoroutine.new()
					thread:run(move_func, self, sx, sy, self.travel_speed)
					--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
				
			
			
		end
	
		
	end

end

function Lifeform:do_eat()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.fs[self.hunger_sel].x, stations.fs[self.hunger_sel].y

	if self.hunger < 0 then
		if stations.fs then
			
				
				local move_func = function(self, x, y, speed)
					local action = self.prop:seekLoc(x,y,speed)
					MOAICoroutine.blockOnAction( action )
					
					local lf = self
					local it = #TM.timers+1
					TM.timers[it] = MOAITimer.new()
					local timer = TM.timers[it]
					timer:setSpan( self.hunger_refresh )
					timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
						function(self)
							print("EAT timer up")
							lf.hunger = lf.hunger_max
							lf.hunger_que = false
							lf:task_manager_next()
							timer:stop()
							timer = nil
						
						end
					)
					
					timer:start()
					
				end
				local thread = MOAICoroutine.new()
				thread:run(move_func, self, sx, sy, self.travel_speed)
				--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
			
			
		end
	
		
	end

end

function Lifeform:do_wash()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.st[self.hygene_sel].x, stations.st[self.hygene_sel].y

	if self.hygene < 0 then
		if stations.st then
			
				
				local move_func = function(self, x, y, speed)
					local action = self.prop:seekLoc(x,y,speed)
					MOAICoroutine.blockOnAction( action )
					
					local lf = self
					local it = #TM.timers+1
					TM.timers[it] = MOAITimer.new()
					local timer = TM.timers[it]
					timer:setSpan( self.hunger_refresh )
					timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
						function(self)
							print("WASH timer up")
							lf.hygene = lf.hygene_max
							lf.hygene_que = false
							lf:task_manager_next()
							timer:stop()
							timer = nil
						
						end
					)
					
					timer:start()
					
				end
				local thread = MOAICoroutine.new()
				thread:run(move_func, self, sx, sy, self.travel_speed)
				--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
			
			
		end
	
		
	end

end

function Lifeform:do_sleep()

	local stations = Lifeform.get_stations(self)
	local sx, sy = stations.sl[self.sleep_sel].x, stations.sl[self.sleep_sel].y

	if self.sleep < 0 then
		if stations.sl then
			
				local move_func = function(self, x, y, speed)
					local action = self.prop:seekLoc(x,y,speed)
					MOAICoroutine.blockOnAction( action )
					
					local lf = self
					local it = #TM.timers+1
					TM.timers[it] = MOAITimer.new()
					local timer = TM.timers[it]
					timer:setSpan( self.hunger_refresh )
					timer:setListener( MOAITimer.EVENT_TIMER_END_SPAN,
						function()
							print("SLEEP timer up")
							lf.sleep = lf.sleep_max
							lf.sleep_que = false
							lf:task_manager_next()
							timer:stop()
							timer = nil
						
						end
					)
					
					timer:start()
					
				end
				local thread = MOAICoroutine.new()
				thread:run(move_func, self, sx, sy, self.travel_speed)
				--move_func(self.ship.stations.st.x, self.ship.stations.st.y, self.travel_speed)
			
			
		end
	
		
	end

end

function Lifeform:get_ship()
	local id = self.ship_id
	local ship = ConstructManager:get_ship(id)
	return ship

end

function Lifeform:get_stations()
	local id = self.ship_id
	--print(id)
	local ship = ConstructManager:get_ship(id)
	
	local a
	
	return ship.stations

end

function Lifeform:get_self()
	local id = self.id
	return LifeManager.lifeforms[id]

end



return Lifeform